#include "player.h"
#include "qgraphicsscene.h"
#include "qtimer.h"
#include<gamedefine.h>
#include <iostream>
#include<anmation.h>
Player::Player() {

}

Player::Player(qreal spawnx, qreal spawny, maploader *map/*,nextmaploder*nextmap*/)
{  //this->nextmap=nextmap;
    this->map=map;
    this->spawnx=spawnx;
    this->spawny=spawny;
    setPixmap(QPixmap(":/gameresource/Fall (32x32).png"));
    m_doubleJumpTimer.setSingleShot(true);
    connect(&m_doubleJumpTimer, &QTimer::timeout, this, [this]() {
        m_canDoubleJump = false;  // 时间窗口结束，禁止二段跳
    });
    x=spawnx;
    y=spawny;
    setPos(spawnx,spawny);
    m_invincibleTimer = new QTimer(this);
    // 连接计时器超时信号到关闭无敌状态的槽函数
    connect(m_invincibleTimer, &QTimer::timeout, this, &Player::endInvincibility);

    m_runAnimation=new anmation(this,"run");
    m_jumpAnimation=new anmation(this,"jump");
    m_doublejumpAnimation=new anmation(this,"doublejump");
    m_hitAnimation=new anmation(this,"hit");
    m_fallAnimation=new anmation(this,"fall");
    m_IdleAnimation=new anmation(this,"idle");
    m_leftrunAnimation=new anmation(this,"leftrun");
    connect(m_runAnimation, &anmation::frameChanged, this, [this](const QPixmap& frame) {
        setPixmap(frame);});
    connect(m_jumpAnimation, &anmation::frameChanged, this, [this](const QPixmap& frame){
        setPixmap(frame);});
    connect(m_hitAnimation, &anmation::frameChanged, this, [this](const QPixmap& frame) {
        setPixmap(frame);});
    connect(m_doublejumpAnimation, &anmation::frameChanged, this, [this](const QPixmap& frame) {
        setPixmap(frame);});
    connect(m_fallAnimation, &anmation::frameChanged, this, [this](const QPixmap& frame) {
        setPixmap(frame);});
    connect(m_IdleAnimation, &anmation::frameChanged, this, [this](const QPixmap& frame) {
        setPixmap(frame);});
    connect(m_leftrunAnimation, &anmation::frameChanged, this, [this](const QPixmap& frame) {
        setPixmap(frame);});
    m_doublejumpAnimation->setLoop(false);
    m_jumpAnimation->setLoop(false);
    m_hitAnimation->setLoop(false);

}


void Player::moveleft()
{
    qDebug()<<"have move recive";
    velocity_x=-100;
    if(is_ground&&!m_leftrunAnimation->animationtimer->isActive()){
        startleftrun();
    }

    //isrunning="leftrunning";
}

void Player::moveright()
{
    velocity_x=100;
    if(is_ground&&!m_runAnimation->animationtimer->isActive()){
        startrun();}

    //isrunning="rightrunning";
}

void Player::jump()
{
    if(is_ground&&!m_canDoubleJump){
        velocity_y=-300;
        m_canDoubleJump = true;           // 允许二段跳
        m_doubleJumpTimer.start(1000);
        startjump();

    }
    else if(!is_ground&&m_canDoubleJump){

        velocity_y=-300;
        m_canDoubleJump = false;          // 禁用后续二段跳
        m_doubleJumpTimer.stop();
        startdoublejump();

    }

}

void Player::stop()
{
    velocity_x=0;
    if(is_ground&&!m_IdleAnimation->animationtimer->isActive()){

        startstop();
    }
    //isrunning="notrunning";
}

void Player::endInvincibility()
{
    m_isInvincible=false;
    m_invincibleTimer->stop();
}

void Player::died()

{   velocity_x=0;
    velocity_y=300;
    m_leftrunAnimation->animationtimer->stop();
    m_runAnimation->animationtimer->stop();
    m_jumpAnimation->animationtimer->stop();
    m_doublejumpAnimation->animationtimer->stop();
    m_fallAnimation->animationtimer->stop();
    m_IdleAnimation->animationtimer->stop();
    m_hitAnimation->animationtimer->start();
}


void Player::startInvincibility()
{
    m_isInvincible = true;
    m_invincibleTimer->start(1000);
}

void Player::collisionwithground(QGraphicsItem *collisionItem)
{   QRectF playerRect = sceneBoundingRect();
    QRectF collisionItemQRectf=collisionItem->sceneBoundingRect();//这里存在一个和三角形碰撞的问题，我们忽略。
    if(playerRect.top()==collisionItemQRectf.bottom()){
        velocity_y=0;
    }
    else if(playerRect.bottom()==collisionItemQRectf.top()){
        velocity_y=0;
        is_ground=true;
    }
   // velocity_y=0;velocity_x=0;
}

void Player::collisionwithenemy()
{   if (m_isInvincible) return;

    if(life>0){
        if(life==2){
            heart->heartshurt();
        }
        else if(life==1){
            heart2->heartshurt();
        }
        life=life-1;
    startInvincibility();
    }
    if(life==0){
        died();
        emit gameover();

    }

}

void Player::collisionwithcodeitem()
{

}

void Player::collisionwithtrapground(QGraphicsItem *collisionItem)
{
    collisionwithground(collisionItem);
    if(is_ground){
        is_ground=false;
        collisionItem->setData(iscollision,false);
    }
}

void Player::collisionwithapple()
{
    qDebug()<<"good";
    applenumber++;
}

void Player::update()
{   updatepoint();//包括碰撞检测的调用其中
    collisionisground();
    setPos(x,y);
    gravity();
    if(applenumber==winapplenumber){
        emit gamewin();

    }

}//实现了位置的更新

void Player::gravity()//模拟重力
{
    if(!is_ground){
        velocity_y=velocity_y+15;
    }
}

void Player::collisionisground()
{
    QRectF currentAABB = boundingRect();
   // QRectF globalAABB = mapToScene(currentAABB).boundingRect(); // 转换为场景坐标
    // 计算扫掠后的全局AABB
    QRectF sweptAABB = mapToScene(currentAABB).boundingRect()
                           .translated(0, 2)
                           .united(mapToScene(currentAABB).boundingRect());
    QList<QGraphicsItem*> candidates = scene()->items(sweptAABB);
    for(QGraphicsItem * other :std::as_const(candidates)){
        is_ground=false;
        if(other->data(iscollision)==true){
            is_ground=true;

        }

    }
}


void Player::updatepoint()
{

    QRectF currentAABB = boundingRect();
    QRectF globalAABB = mapToScene(currentAABB).boundingRect(); // 转换为场景坐标
    // 计算扫掠后的全局AABB
    QRectF sweptAABB = mapToScene(currentAABB).boundingRect()
                           .translated(velocity_x*1/60, velocity_y*1/60)
                           .united(mapToScene(currentAABB).boundingRect());

    QList<QGraphicsItem*> candidates = scene()->items(sweptAABB);//将可能碰撞到的物体全部提取出来，处理最先碰到的物体。
    qreal t=1.0/60;qreal realtimex=1.0/60,realtimey=1.0/60;
    QGraphicsItem *collisionItem=nullptr;
    for(QGraphicsItem * other :std::as_const(candidates)){
        qreal timex=t;qreal timey=t;
        if(other==this)continue;
        if(other->data(iscollision).toBool()!=true){continue;

        }
        QRectF otheraabb = other->sceneBoundingRect();
        // QRectF globalotherAABB=mapToScene(otheraabb).boundingRect();
        QRectF globalotherAABB=otheraabb;
        qreal collisiontime= sweptTest(globalAABB, globalotherAABB,timex,timey);

        if (collisiontime <= t) {
            t = collisiontime;
            collisionItem=other;
            realtimex=timex;
            realtimey=timey;
        }
    }//存在非常大的特殊形状碰撞问题。
   if(collisionItem!=nullptr){
        switch(collisionItem->data(ObjectType).toInt()){
        case 1:collisionwithground(collisionItem);break;
        case 2:{collisionwithtrapground(collisionItem); break;}
        case 3:collisionwithenemy();break;
        case 4:collisionwithcodeitem();break;
        case 5:{collisionwithapple();


            map->damageappleonint->append(collisionItem->scenePos());

            QGraphicsScene* tempscene = collisionItem->scene();

            if (tempscene) {
                tempscene->removeItem(collisionItem);
            }
            delete collisionItem;
            collisionItem = nullptr;
            break;}

        }//我无法理解为什么加上背景就出问题了，我记得这种检测在之前我用另外一个地图的时候根本不会出问题，背景能够正常跳过，但是这里不知道为什么背景他碰撞到就不能动了，会使realtimex=0，但是按理根本不应该改变real啊，他根本进不去


    }
   //if(realtimex==0){qDebug()<<"realtimex=o";}
    x=velocity_x*realtimex+x;
    y=velocity_y*realtimey+y;//是否需要将X，Y分开我们后面再处理


}

qreal Player::sweptTest(QRectF a, QRectF b,qreal&timex,qreal&timey)
{
    qreal entryX;
    if (b.left()>=a.right()) {
        entryX = b.left() - a.right();

        timex=entryX/qAbs(velocity_x);//这里要注意，x没有速度时是不会进入这些if中，有速度的时候，只要控制好y的速度变化，应该也可以避免bug
    }
    else if(b.right()<=a.left()){
        entryX = a.left() - b.right();
        timex=entryX/qAbs(velocity_x);
    }


    // 计算进入和退出时间（Y轴）
    qreal entryY;
    if (b.top()>=a.bottom()) {
        entryY = b.top() - a.bottom();
        timey=entryY/qAbs(velocity_y);

    } else if(a.top()>=b.bottom()) {
        entryY = a.top() - b.bottom();
        timey=entryY/(qAbs(velocity_y));std::cout<<"a.top()=="<<a.top()<<"b.bottom=="<<b.bottom();
    }


    return timey>=timex?timex:timey;
}

void Player::restart()
{
    heart->hearrecover();
    heart2->hearrecover();
    applenumber=0;
    x=spawnx;
    y=spawny;
    life=2;
}

void Player::setwinapplenumber(int number)
{
    winapplenumber=number;
}

void Player::startrun()
{   m_leftrunAnimation->stop();
    m_IdleAnimation->stop();
    m_runAnimation->start();
}

void Player::startstop()
{
    m_leftrunAnimation->stop();
    m_runAnimation->stop();
    m_IdleAnimation->start();

}

void Player::startleftrun()
{

    m_IdleAnimation->stop();
    m_runAnimation->stop();
    m_leftrunAnimation->start();
}

void Player::startjump()
{
    m_IdleAnimation->stop();
    m_runAnimation->stop();
    m_leftrunAnimation->stop();
    m_jumpAnimation->start();
}

void Player::startdoublejump()
{
    m_jumpAnimation->stop();
    m_doublejumpAnimation->start();
}


